package org.budo.redis.jdbc.driver;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import org.budo.jdbc.driver.AbstractBudoJdbcDriver;
import org.budo.jdbc.driver.JdbcUrl;
import org.budo.jdbc.driver.parser.SqlStatementParser;
import org.budo.jdbc.driver.parser.cache.CachedJdbcStatementParser;
import org.budo.redis.jdbc.driver.executor.AbstractRedisStatementExecutor;
import org.budo.redis.jdbc.driver.parser.impl.DefaultRedisStatementParser;

/**
 * 入口类，实现了java.sql.Driver接口
 * 
 * @author lmw
 */
public class BudoRedisJdbcDriver extends AbstractBudoJdbcDriver {
    private static final SqlStatementParser DEFAULT_STATEMENT_PARSER = new CachedJdbcStatementParser() //
            .setStatementParser(new DefaultRedisStatementParser());

    public static final String[] URL_PREFIX = { "jdbc:mysql://", "jdbc:redis://" };

    private static final int DEFAULT_PORT = 6379;

    static {
        try {
            DriverManager.registerDriver(new BudoRedisJdbcDriver()); // 类加载时注册驱动
        } catch (Throwable e) {
            throw new IllegalStateException("#38 Can't register driver!", e);
        }
    }

    @Override
    public boolean acceptsURL(String url) throws SQLException {
        return JdbcUrl.acceptsURL(url, URL_PREFIX);
    }

    /**
     * 获取连接
     * 
     * @param url 形如 jdbc:redis://127.0.0.1:6379/0
     */
    @Override
    public Connection connect(String url, Properties info) throws SQLException {
        JdbcUrl jdbcUrl = JdbcUrl.parse(url, URL_PREFIX, DEFAULT_PORT);
        String password = null == info ? null : info.getProperty("password");

        AbstractRedisStatementExecutor statementExecutor = this.statementExecutor();
        statementExecutor.setJdbcUrl(jdbcUrl);
        statementExecutor.setPassword(password);

        BudoRedisJdbcConnection connection = new BudoRedisJdbcConnection();
        connection.setStatementParser(DEFAULT_STATEMENT_PARSER);
        connection.setStatementExecutor(statementExecutor);
        return connection;
    }

    protected AbstractRedisStatementExecutor statementExecutor() {
        // org.budo.redis.jdbc.driver.executor.jedis.BudoJedisRedisStatementExecutor();
        return new org.budo.redis.jdbc.driver.executor.socket.BudoSocketRedisStatementExecutor();
    }
}